#!/usr/bin/python3
# -*- coding: utf-8 -*-
# class Thread(group=None, target=None, name=None, args=(), keargs={})
# 构造函数能带有关键字参数被调用。这些参数是:
# group 应当为 None，为将来实现Python Thread类的扩展而保留。
# target 是被 run()方法调用的回调对象. 默认应为None, 意味着没有对象被调用。
# name 为线程名字。默认形式为’Thread-N’的唯一的名字被创建，其中N 是比较小的十进制数。
# args是目标调用参数的tuple，默认为空元组()。
# kwargs是目标调用的参数的关键字dictionary，默认为{}。

# 守护线程含义
# 一般可以将不重要或者不允许离开主线程独立运行的线程设置成为守护线程。
# 一旦将某个线程设置为守护线程，则该线程会在主线程结束的时候自动退出。
# 守护线程必须设置在start()之前设置。否则无效
import threading
import time
from threading import Thread


def func(name='English'):
    for i in range(3):
        print('线程：', name)
        time.sleep(1)


if __name__ == '__main__':
    # 实例化Thread对象
    # target参数一定为一个函数，且不带括号
    # args参数为元组类型，参数为一个时一定要加逗号
    thread1 = Thread(target=func, args=('Daniel',))
    thread1.start()
    # join(timeout=None)：阻塞子线程，待子线程结束后，再往下执行（挂起线程）。在 join() 后调用 is_alive() 才能判断是否发生超时，如果线程仍然存活，则 join() 超时。当 timeout 参数不存在或者是 None ，这个操作会阻塞直到线程终结。一个线程可以被 join() 很多次。
    thread1.join()
    # is_alive()：返回线程是否存活。
    print(thread1.is_alive())

    # daemon：一个表示这个线程是（True）否（False）守护线程的布尔值。一定要在调用 start() 前设置好，不然会抛出 RuntimeError 。
    thread2 = Thread(target=func, args=('Alice',))
    # 设置守护线程(两种)，线程是否随主线程退出而退出，默认为False
    # thread2.daemon=True
    thread2.setDaemon(True)
    thread2.start()
    # 判断是否为守护线程
    print(thread2.isDaemon())

    # 主线程
    print(threading.current_thread().getName())

    # 返回当前对应调用者的控制线程的 Thread 对象。如果调用者的控制线程不是利用 threading 创建，会返回一个功能受限的虚拟线程对象。
    print(threading.current_thread())  # 主线程

    # 返回当前存活的连同主线程在内的线程
    print(threading.enumerate())

    # 返回当前存活的 Thread 对象的数量。 返回值与 enumerate() 所返回的列表长度一致。
    print(threading.active_count())

    # 返回主 Thread 对象。一般情况下，主线程是Python解释器开始时创建的线程。
    print(threading.main_thread())  # 主线程

    print(thread1.getName())  # 线程名

# https://docs.python.org/zh-cn/3/library/threading.html
